Hellforge Crackme II (Coded by Lazarus)

Tutorial by Rayden

 

 

Well, first I have to say (like everytime) that I am german, and so I aplogize for my english which isnt perfect yet :). But everyxone should be able to understand me :=).

This is not a "Step by Step" toturial, else it would be much too long, I just describe the steps you _must_ know to solve it.

Target: Hellfroge Crackme II

Tools needed: SoftIce 3.2x, not more not less. U also may use a Disassembler to look for suspicious stringd or jumps, but ist not neccessary. I assue you have basic knowledge of Softice Usage.

Ok, lets start enter your name (‘Rayden’ for me), and enter a serial. Before you click on the Chck-button, now go to SoftIce and set a breakpoint on Hmemcpy.

After you pressed the check button and some short time of tracing with F10, make sure you are back at the Crackme’s code and trace until you are at line:

:00426897 A194864200 mov eax, dword ptr [00428694]

:0042689C E86FEDFDFF call 00405610 Returns length of Name in EAX

:004268A1 83F804 cmp eax, 00000004 Length is compared with 4

:004268A4 7D1B jge 004268C1 if name>=4 jump good cracker

:004268A6 6A00 push 00000000 else jump away "bad cracker"

* Possible StringData Ref from Code Obj ->"Sorry"

|

:004268A8 B9DC694200 mov ecx, 004269DC

* Possible StringData Ref from Code Obj ->"Wrong Code"

|

:004268AD BAE4694200 mov edx, 004269E4

:004268B2 A124864200 mov eax, dword ptr [00428624]

:004268B7 E84CB3FFFF call 00421C08

:004268BC E9E8000000 jmp 004269A9

Well the Call at 00405610 should return the length of your name. In my case ‘6’. Then the length is compared with ‘4’ at 004268A1. this is the first check. If U entered a name shorter than 4 chars you will get the "Wrong Code" Message. But if your name is at least 4 chars you will take the first check and you will jump away to 004268C1. Ok, now lets continoue

The following code , which you will jump to when your name is at least 4 chars, will generate the real serial from the name you entered. we will have a closer look at it now:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004268A4(C)

|

:004268C1 8D55FC lea edx, dword ptr [ebp-04]

 

:004268C4 8B83B0010000 mov eax, dword ptr [ebx+000001B0]

 

:004268CA E881B3FEFF call 00411C50

 

:004268CF 8B45FC mov eax, dword ptr [ebp-04]

Points to our name

:004268D2 0FB600 movzx eax, byte ptr [eax]

Load hexvalue of first char of name into EAX

:004268D5 8BF0 mov esi, eax

Moves the value from EAX into ESI

:004268D7 C1E602 shl esi, 02

Shiftleft ESI two times

:004268DA 8D3476 lea esi, dword ptr [esi+2*esi]

ESI=ESI*2+ESI and stored in ESI

:004268DD 8D55F8 lea edx, dword ptr [ebp-08]

 

:004268E0 8B83B0010000 mov eax, dword ptr [ebx+000001B0]

 

:004268E6 E865B3FEFF call 00411C50

 

:004268EB 8B45F8 mov eax, dword ptr [ebp-08]

Again our name

:004268EE 0FB64001 movzx eax, byte ptr [eax+01]

Loads the hex value of the 2nd char into EAX

:004268F2 8D0480 lea eax, dword ptr [eax+4*eax]

=EAX=EAX+4*EAX

:004268F5 8D0480 lea eax, dword ptr [eax+4*eax]

NEW VALUE OF EAX=NEW VALUE OF EAX*4+NEW VALUE OF EAX

This operation uses the result of 004268F2 for its operation NOT the hexvalue of our 2nd char, which was originally stored in EAX !

:004268F8 03F0 add esi, eax

result added to ESI (now ESI stored the restult from the math oerartions from our first and second char.

:004268FA 8D55F4 lea edx, dword ptr [ebp-0C]

 

:004268FD 8B83B0010000 mov eax, dword ptr [ebx+000001B0]

 

:00426903 E848B3FEFF call 00411C50

 

:00426908 8B45F4 mov eax, dword ptr [ebp-0C]

Again our name...

:0042690B 0FB64002 movzx eax, byte ptr [eax+02]

Loads the hexvalue of our 3rd char into EAX

:0042690F 03C0 add eax, eax

Double it

:00426911 03F0 add esi, eax

And ADD it too ESI

:00426913 8D55F0 lea edx, dword ptr [ebp-10]

 

:00426916 8B83B0010000 mov eax, dword ptr [ebx+000001B0]

 

:0042691C E82FB3FEFF call 00411C50

 

:00426921 8B45F0 mov eax, dword ptr [ebp-10]

Again our name...

:00426924 0FB64003 movzx eax, byte ptr [eax+03]

Points to the fourth char of our name and store hexvalue of it in EAX

:00426928 6BC00B imul eax, 0000000B

Multiply with 0bh (11 dec)

:0042692B 03F0 add esi, eax

And add it to ESI

 

Well, the above code uses the first four chars of our name to make some calculations for the real serial. Now u know why our name must be at least 4 chars long :). Following you will find the final maths, which will generate our real serial:

 

 

:0042692D 893590864200 mov dword ptr [00428690], esi

Move result of name-maths to some mem-location

:00426933 A194864200 mov eax, dword ptr [00428694]

 

:00426938 E8D3ECFDFF call 00405610

Again our name...

:0042693D 8B1590864200 mov edx, dword ptr [00428690]

Move result of name-maths to EDX (it was stored in this mem-location at 0042692D)

:00426943 0FAF1590864200 imul edx, dword ptr [00428690]

EDX*EDX

:0042694A F7EA imul edx

EDX*EAX (lenght of our name which is stored in EAX. This operation also stores our REAL serial in EAX. U now could type ? EAX in softice and u will get it.

:0042694C A390864200 mov dword ptr [00428690], eax

 

:00426951 8D55EC lea edx, dword ptr [ebp-14]

 

:00426954 A190864200 mov eax, dword ptr [00428690]

 

:00426959 E806EBFDFF call 00405464

 

:0042695E 8B45EC mov eax, dword ptr [ebp-14]

 

:00426961 50 push eax

 

:00426962 8D55FC lea edx, dword ptr [ebp-04]

 

:00426965 8B83B4010000 mov eax, dword ptr [ebx+000001B4]

 

:0042696B E8E0B2FEFF call 00411C50

 

:00426970 8B55FC mov edx, dword ptr [ebp-04]

Our entered serial

:00426973 58 pop eax

The real serial

:00426974 E8FBCAFDFF call 00403474

The call which compares our real serial with the serial we entered

:00426979 7518 jne 00426993

Bad Cracker jump away...

:0042697B 6A00 push 00000000

 

 

 

Ok, now, since we know a serial is calculated lets try it. I will show the way how to calculate the serial for ‘Rayden’ in Hex:

Name: R a y d e n

Hex : 52 61 79 64 65 6e

 

1. Calculate the result for Char ‘R’:

<52> SHL, 2 Times = <148>; <148> * 2 + <148> = 03d8h

2. Calculate the result for Char ‘a’:

<61> * 4 = <184> + <61> = <01E5>; <01E5> * 4 + <01E5> = 0979h

3. Calculate the result for Char ‘y’:

<79> * 2 = 00F2h

4. Calculate the result for Char ‘d’:

<64> * 0B = 044Ch

----------

Total: = 128Fh

 

5. The last 2 final maths with our previous result:

<128F> * <128F> = <01586BE1>, <01586BE1> * 6 =08218746h

 

Ok, our real serial in hex is 08218746h, which is 135432006 decimal

The solution for me is then:

Name: Rayden

Serial: 135432006

Final notes:

Well, ist as Lazarus said: Nothing special here, just some maths here and there and a conditional jump. Here are some final notes about the crackme/serial:

- Name is case-sensitive

- Name must be at least 4 chars, else you’ll fail

- The first math-routine uses our first 4 chars to calculate a checkvalue

- The lenght of our name is used to calculate the final serial

- You simply could reverse the cond. jump to beat it (but we wont this <g>)

- You also could fish the real serial at some mem. location.

 

Job done.

contact: rayden_@hotmail.com